package com.ibm.cps.sql.netsfparser;

import net.sf.jsqlparser.expression.BinaryExpression;
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
import net.sf.jsqlparser.expression.operators.relational.GreaterThanEquals;
import net.sf.jsqlparser.expression.operators.relational.MinorThan;
import net.sf.jsqlparser.expression.operators.relational.MinorThanEquals;
import net.sf.jsqlparser.expression.operators.relational.NotEqualsTo;
import net.sf.jsqlparser.expression.operators.relational.OldOracleJoinBinaryExpression;

import com.ibm.cps.sql.expression.BooleanExpression;
import com.ibm.cps.sql.expression.ComparisonExpression;
import com.ibm.cps.sql.expression.ConditionCompositionExpression;
import com.ibm.cps.sql.expression.ValueExpression;

public class ConditionParser extends ExpressionVisitorAdapter {
	private BooleanExpression expression;

	public BooleanExpression getExpression() {
		return expression;
	}

	@Override
	public void visit(AndExpression arg0) {
		this.expression = parseConditionComposition(ConditionCompositionExpression.Predicate.AND, arg0);
	}

	@Override
	public void visit(OrExpression arg0) {
		this.expression = parseConditionComposition(ConditionCompositionExpression.Predicate.OR, arg0);
	}
	
	private ConditionCompositionExpression parseConditionComposition(ConditionCompositionExpression.Predicate predicate, BinaryExpression expression){
		ConditionParser parser = new ConditionParser();
		expression.getLeftExpression().accept(parser);
		BooleanExpression leftNode = parser.getExpression();
		expression.getRightExpression().accept(parser);
		BooleanExpression rightNode = parser.getExpression();
		return new ConditionCompositionExpression(leftNode, rightNode, predicate);
	}

	@Override
	public void visit(EqualsTo arg0) {
		this.expression = parseComparionExpression(ComparisonExpression.Operator.EQUALS, arg0);
	}

	@Override
	public void visit(GreaterThan arg0) {
		this.expression = parseComparionExpression(ComparisonExpression.Operator.GREATER_THAN, arg0);
	}

	@Override
	public void visit(GreaterThanEquals arg0) {
		this.expression = parseComparionExpression(ComparisonExpression.Operator.GREATER_THAN_EQUALS, arg0);
	}

	@Override
	public void visit(MinorThan arg0) {
		this.expression = parseComparionExpression(ComparisonExpression.Operator.LESS_THAN, arg0);
	}

	@Override
	public void visit(MinorThanEquals arg0) {
		this.expression = parseComparionExpression(ComparisonExpression.Operator.LESS_THAN_EQUALS, arg0);
	}

	@Override
	public void visit(NotEqualsTo arg0) {
		this.expression = parseComparionExpression(ComparisonExpression.Operator.NOT_EQUALS, arg0);
	}
	
	private ComparisonExpression parseComparionExpression(ComparisonExpression.Operator operator, OldOracleJoinBinaryExpression expression){
		ValueExpressionParser parser = new ValueExpressionParser();
		expression.getLeftExpression().accept(parser);
		ValueExpression leftNode = parser.getExpression();
		expression.getRightExpression().accept(parser);
		ValueExpression rightNode = parser.getExpression();
		return new ComparisonExpression(operator, leftNode, rightNode);
	}

}
